<?php
// PDO操作类
class DataObject
{
  protected $pdo;
  protected $res;
  private $lastID;
  private $sql;

  public function __construct()
  {
    $this->connect_mysql(DATA_TYPE, DATA_HOST, DATA_NAME, DATA_USERNAME, DATA_PASSWORD);
  }

  public function connect($data_str, $db_user, $db_psw)
  {
    try {
      $this->pdo = new PDO($data_str, $db_user, $db_psw);
      $this->pdo->query('set names utf8;');
      $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
      die("Error!: " . $e->getMessage() . "<br/>");
    }
  }

  // 连接数据库
  public function connect_mysql($db_type, $db_host, $db_name, $db_user, $db_psw)
  {
    try {
      $this->pdo = new PDO("$db_type:host=$db_host;dbname=$db_name", $db_user, $db_psw);
      $this->pdo->query('set names utf8;');
      $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
      die("Error: " . $e->getMessage() . "<br/>");
    }
  }

  // 查询
  public function query($sql, $parse = true)
  {
    $this->sql = $parse ? Sql::parse($sql) : $sql;
    try {
      $res = $this->pdo->query($this->sql);

      // 设置PDO错误模式为异常
      // $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

      // $input = "O'Reilly";

      // 使用预处理语句和绑定参数
      // $stmt = $this->pdo->prepare($this->sql);
      // $stmt->execute();

      // 获取结果集
      // $res = $stmt->fetchAll(PDO::FETCH_ASSOC);

      // ... 处理结果 ...
    } catch (PDOException $e) {
      // alert_href($GLOBALS['lang']['illegal'], './');
      die("Error: " . $e->getMessage() . "<br/>");
    }

    $this->res = $res;
    return $res;
  }

  function sql($sql, $parse = true)
  {
    echo $parse ? Sql::parse($sql) : $sql;
    return;
  }

  // 执行
  function exec($sql, $parse = true)
  {
    $this->sql = $parse ? Sql::parse($sql) : $sql;

    try {
      $this->pdo->beginTransaction();
      $this->pdo->exec($this->sql);
      $this->pdo->commit();
    } catch (Exception $e) {
      $this->pdo->rollBack();
      echo 'Failed:' . $e->getMessage();
      exit();
    }

    $this->lastID = $this->pdo->lastInsertId();
    return max(intval($this->lastID), 1);

    // $this->pdo->prepare($sql);
    // return $this->pdo->exec();
  }

  // 获取值
  public function getOne($sql, $parse = true, $limited = false)
  {
    if ($limited) {
      $sql = trim($sql . " LIMIT 1");
    }

    $res = $this->query($sql, $parse);

    if ($res !== false) {
      $row = !empty($res) ? $this->res->fetchColumn() : false;
      $this->res = $row;
      return $row !== false ? $row : '';
    }

    return false;
  }

  // 获取行
  public function getRow($sql, $parse = true, $limited = true, $type = '')
  {
    if ($limited) {
      $sql = trim($sql . " LIMIT 1");
    }
    $res = $this->query($sql, $parse);
    if ($res !== false) {
      $this->res = $type ? $res->fetchObject() : $res->fetch(PDO::FETCH_ASSOC);
      return $this->res;
    }
    return false;
  }

  // 获取列
  public function getCol($sql, $parse = true)
  {
    $res = $this->query($sql, $parse);
    if ($res !== false) {
      $arr = array();
      while ($row = $res->fetchColumn()) {
        $arr[] = $row;
      }
      $this->res = $arr;
      return $arr;
    }
    return false;
  }

  // 获取所有行
  public function getAll($sql, $parse = true, $type = 0)
  {
    $res = $this->query($sql, $parse);
    if ($res !== false && $res !== null) {
      $this->res = $type ? $res->fetchAll(PDO::FETCH_OBJ) : $res->fetchAll(PDO::FETCH_ASSOC);
      return $this->res;
    }
    return false;
  }

  // 数组自动插入/更新表数据
  public function autoExecute($table, $field_values, $mode = 'INSERT', $where = '', $parse = true)
  {
    $mode = strtoupper($mode);
    $field_names = $this->getCol('DESC ' . DATA_PREFIX . $table);
    $sql = '';
    if ($mode == 'INSERT') {
      $fields = $values = array();
      foreach ($field_names as $value) {
        if (array_key_exists($value, $field_values)) {
          $fields[] = $value;
          $values[] = $field_values[$value] === NULL ? 'NULL' : '\'' . $field_values[$value] . '\'';
        }
      }
      if (!empty($fields)) {
        $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
      }
    } else {
      $sets = array();
      foreach ($field_names as $value) {
        if (array_key_exists($value, $field_values)) {
          $sets[] = $field_values[$value] === NULL ? $value . ' = NULL' : $value . ' = \'' . $field_values[$value] . '\'';
        }
      }
      if (!empty($sets)) {
        $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $where;
      }
    }
    // dd($sql);

    if ($sql != '') {
      $this->res = $this->exec($sql, $parse);
      return $this->res;
    }
    return false;
  }

  // 获取最新生成id
  public function getLastID()
  {
    return $this->lastID;
  }

  // 获取最大id
  public function getMaxID($table, $field, $sql = '')
  {
    $res = !empty($sql) ? $this->getOne("SELECT MAX({$field}) FROM {$table} WHERE {$sql}") : $this->getOne("SELECT MAX({$field}) FROM {$table}");

    $this->res = intval($res);
    return $this->res;
  }

  // 关闭连接
  public function close()
  {
    $this->pdo = null;
  }

  // 清空表
  public function truncate($table)
  {
    return $this->exec('TRUNCATE TABLE ' . $table);
  }

  // 删除表
  public function drop($table)
  {
    return $this->exec('DROP TABLE ' . $table);
  }

  // 删除库
  public function dropDB($db)
  {
    return $this->exec('DROP DATABASE ' . $db);
  }

  public function __destruct()
  {
    $this->close();
  }
}
